home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / gprof / i386.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  2.9 KB  |  111 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19. #include "gprof.h"
  20. #include "cg_arcs.h"
  21. #include "core.h"
  22. #include "hist.h"
  23. #include "symtab.h"
  24.  
  25.  
  26. int
  27. DEFUN (iscall, (ip), unsigned char *ip)
  28. {
  29.   if (*ip == 0xeb || *ip == 0x9a)
  30.     return 1;
  31.   return 0;
  32. }
  33.  
  34.  
  35. void
  36. find_call (parent, p_lowpc, p_highpc)
  37.      Sym *parent;
  38.      bfd_vma p_lowpc;
  39.      bfd_vma p_highpc;
  40. {
  41.   unsigned char *instructp;
  42.   long length;
  43.   Sym *child;
  44.   bfd_vma destpc;
  45.  
  46.   if (core_text_space == 0)
  47.     {
  48.       return;
  49.     }
  50.   if (p_lowpc < s_lowpc)
  51.     {
  52.       p_lowpc = s_lowpc;
  53.     }
  54.   if (p_highpc > s_highpc)
  55.     {
  56.       p_highpc = s_highpc;
  57.     }
  58.   DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
  59.               parent->name, p_lowpc, p_highpc));
  60.   for (instructp = (unsigned char *) core_text_space + p_lowpc;
  61.        instructp < (unsigned char *) core_text_space + p_highpc;
  62.        instructp += length)
  63.     {
  64.       length = 1;
  65.       if (iscall (instructp))
  66.     {
  67.       DBG (CALLDEBUG,
  68.            printf ("[findcall]\t0x%x:callf",
  69.                instructp - (unsigned char *) core_text_space));
  70.       length = 4;
  71.       /*
  72.        *  regular pc relative addressing
  73.        *    check that this is the address of 
  74.        *    a function.
  75.        */
  76.       destpc = ((bfd_vma) instructp + 5 - (bfd_vma) core_text_space);
  77.       if (destpc >= s_lowpc && destpc <= s_highpc)
  78.         {
  79.           child = sym_lookup (&symtab, destpc);
  80.           DBG (CALLDEBUG,
  81.            printf ("[findcall]\tdestpc 0x%lx", destpc);
  82.            printf (" child->name %s", child->name);
  83.            printf (" child->addr 0x%lx\n", child->addr);
  84.         );
  85.           if (child->addr == destpc)
  86.         {
  87.           /*
  88.            *      a hit
  89.            */
  90.           arc_add (parent, child, (long) 0);
  91.           length += 4;    /* constant lengths */
  92.           continue;
  93.         }
  94.           goto botched;
  95.         }
  96.       /*
  97.        *  else:
  98.        *    it looked like a callf,
  99.        *    but it wasn't to anywhere.
  100.        */
  101.     botched:
  102.       /*
  103.        *  something funny going on.
  104.        */
  105.       DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n"));
  106.       length = 1;
  107.       continue;
  108.     }
  109.     }
  110. }
  111.